/***************************************************************************
 * Copyright (C) 2012
 * by Dj_Skual
 *
 * Original ListBrowser by Tantric (C) 2009
 *
 * This software is provided 'as-is', without any express or implied
 * warranty. In no event will the authors be held liable for any
 * damages arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any
 * purpose, including commercial applications, and to alter it and
 * redistribute it freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you
 * must not claim that you wrote the original software. If you use
 * this software in a product, an acknowledgment in the product
 * documentation would be appreciated but is not required.
 *
 * 2. Altered source versions must be plainly marked as such, and
 * must not be misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source
 * distribution.
 *
 * for SaveGame Manager GX 2012
 ***************************************************************************/
#include "IconMiiBrowser.hpp"
#include "../../Themes/CTheme.h"
#include "../../Controls/Application.h"

/**
 * Constructor for the IconMiiBrowser class.
 */
IconMiiBrowser::IconMiiBrowser(Browser * miibrowser, int w, int h)
	: GuiFileBrowser(miibrowser, w, h)
{
	selectedItem = 0;
	pageIndex = 0;
	forceReload = true;
	numEntries = browser->GetEntrieCount();
	
	browser->ListChanged.connect(this, &IconMiiBrowser::OnBrowserListChange);

	trigA = new GuiTrigger;
	trigA->SetSimpleTrigger(-1, WiiControls.ClickButton | ClassicControls.ClickButton << 16, GCControls.ClickButton);

	btnSoundClick = Resources::GetSound("button_click.wav");

	bgFileSelection = Resources::GetImageData("browser_entry_bg.png");
	fileMii = Resources::GetImageData("icon_brows_mii.png");
	
	scrollbar = new Scrollbar(height + 20, Scrollbar::ICONMODE);
	scrollbar->SetAlignment(ALIGN_RIGHT | ALIGN_TOP);
	scrollbar->SetPosition(4, -10);
	scrollbar->SetScrollSpeed(Settings.ScrollSpeed);
	scrollbar->SetDPadControl(false);
	scrollbar->listChanged.connect(this, &IconMiiBrowser::OnListChange);
	
	RowSize = (width-scrollbar->GetWidth())/90;
	PageSize = RowSize*height/90;
	
	for(int i = 0; i < PageSize; ++i)
		AddButton();
	for(int i = 0; i < PageSize; ++i)
		AddTTButton();
	
	scrollbar->SetEntrieCount(numEntries);
	scrollbar->SetPageSize(PageSize);
	scrollbar->SetRowSize(RowSize);
	scrollbar->SetSelected(0, 0);
	Append(scrollbar);
	
	SetVisible(false);
	VisibleChanged.connect(this, &IconMiiBrowser::OnVisibleChange);
}

/**
 * Destructor for the IconMiiBrowser class.
 */
IconMiiBrowser::~IconMiiBrowser()
{
	RemoveAll();
	
	Resources::Remove(bgFileSelection);
	Resources::Remove(fileMii);
	
	Resources::Remove(btnSoundClick);
	
	delete trigA;

	delete scrollbar;
	
	while(!fileBtn.empty())
		RemoveButton(0);
}

void IconMiiBrowser::AddButton()
{
	int size = fileBtn.size();

	fileSelectionImg.resize(size+1);
	fileSelectionImg[size] = new GuiImage(bgFileSelection);
	fileSelectionImg[size]->SetAlignment(ALIGN_CENTER | ALIGN_TOP);
	fileSelectionImg[size]->SetPosition(0, -7);
	
	fileBtnIcon.resize(size+1);
	fileBtnIcon[size] = new GuiImage(fileMii);
	fileBtnIcon[size]->SetAlignment(ALIGN_CENTER | ALIGN_TOP);
	fileBtnIcon[size]->SetPosition(0, 10);
	
	fileBtnText.resize(size+1);
	fileBtnText[size] = new GuiText((char*) NULL, 14, thColor("r=0 g=0 b=0 a=255 - mainbrowser entry text color"));
	fileBtnText[size]->SetAlignment(ALIGN_CENTER | ALIGN_BOTTOM);
	fileBtnText[size]->SetPosition(0, -20);
	fileBtnText[size]->SetLinesToDraw(2);
	fileBtnText[size]->SetMaxWidth(fileMii->GetWidth() + 33, WRAP);

	fileBtn.resize(size+1);
	fileBtn[size] = new GuiButton(90,90);
	fileBtn[size]->SetImageOver(fileSelectionImg[size]);
	fileBtn[size]->SetIcon(fileBtnIcon[size]);
	fileBtn[size]->SetLabel(fileBtnText[size]);
	fileBtn[size]->SetTrigger(trigA);
	fileBtn[size]->SetSoundClick(btnSoundClick);
	fileBtn[size]->SetRumble(Settings.BrowserRumble);
	fileBtn[size]->Clicked.connect(this, &IconMiiBrowser::OnClicked);
	fileBtn[size]->StateChanged.connect(this, &IconMiiBrowser::OnButtonStateChange);
	fileBtn[size]->SetState(STATE_DISABLED);
	
	Append(fileBtn[size]);
}

void IconMiiBrowser::AddTTButton()
{
	int size = tooltipBtn.size();

	tooltip.resize(size+1);
	tooltip[size] = new GuiTooltip((char*) NULL);
	tooltip[size]->SetAlignment(ALIGN_LEFT | ALIGN_TOP);
	tooltip[size]->SetMaxWidth(width-95);

	tooltipBtn.resize(size+1);
	tooltipBtn[size] = new GuiButton(90,90);
	tooltipBtn[size]->SetTooltip(tooltip[size]);
	tooltipBtn[size]->SetRumble(false);
	tooltipBtn[size]->SetState(STATE_DISABLED);
	
	Append(tooltipBtn[size]);
}

void IconMiiBrowser::RemoveButton(int i)
{
	if(i < 0 || i >= (int) fileBtn.size())
		return;

	if(tooltip[i])
		delete tooltip[i];
	if(tooltipBtn[i])
		delete tooltipBtn[i];
	if(fileBtnText[i])
		delete fileBtnText[i];
	if(fileSelectionImg[i])
		delete fileSelectionImg[i];
	if(fileBtnIcon[i])
		delete fileBtnIcon[i];
	if(fileBtn[i])
		delete fileBtn[i];

	tooltip.erase(tooltip.begin()+i);
	tooltipBtn.erase(tooltipBtn.begin()+i);
	fileBtnText.erase(fileBtnText.begin()+i);
	fileSelectionImg.erase(fileSelectionImg.begin()+i);
	fileBtnIcon.erase(fileBtnIcon.begin()+i);
	fileBtn.erase(fileBtn.begin()+i);
}

void IconMiiBrowser::SetListRumble()
{
	for(int i = 0; i < (int)fileBtn.size(); i++)
		fileBtn[i]->SetRumble(Settings.BrowserRumble);
}

void IconMiiBrowser::OnVisibleChange(GuiElement *sender UNUSED, bool Visible)
{
	if(Visible)
	{
		forceReload = true;
		OnListChange(selectedItem, pageIndex);
	}
}

void IconMiiBrowser::OnClicked(GuiButton *sender, int pointer UNUSED, const POINT &p UNUSED)
{
	Application::Instance()->ResetPads();
	
	for(u32 i = 0; i < fileBtn.size(); i++)
	{
		if(fileBtn[i] == sender)
		{
			Clicked(i);
			break;
		}
	}
}

void IconMiiBrowser::OnButtonStateChange(GuiElement *sender, int state, int stateChan UNUSED)
{
	if(scrollbar->BoxIsHolded())
		goto jump;
	
	for(int i = 0; i < PageSize && i < numEntries; i++)
	{
		if(sender == fileBtn[i])
		{
			if(state == STATE_SELECTED)
			{
				selectedItem = i;
				browser->SetSelectedIndex(pageIndex+i);
				break;
			}
		}
	}
	
  jump:
	
	if(fileBtn[selectedItem]->GetState() == STATE_DEFAULT)
		fileBtn[selectedItem]->_SetState(STATE_SELECTED);
	
	scrollbar->SetSelectedItem(selectedItem);
}

void IconMiiBrowser::OnListChange(int selItem, int selIndex)
{
	static bool changing = false;
	if(changing)
		return;
	changing = true;
	
	bool reloadNeeded = false;
	if((pageIndex != selIndex) || forceReload)
		reloadNeeded = true;
	forceReload = false;
	
	pageIndex = selIndex;
	selectedItem = selItem;
	browser->SetSelectedIndex(selIndex+selItem);
	
	u16 x = 12, y = 0;
	
	for(int i = 0; i < PageSize && reloadNeeded; i++)
	{
		if(selIndex+i < numEntries)
		{
			if(fileBtn[i]->GetState() == STATE_DISABLED)
			{
				fileBtn[i]->SetVisible(true);
				fileBtn[i]->SetState(STATE_DEFAULT);
				tooltipBtn[i]->SetVisible(true);
				tooltipBtn[i]->SetState(STATE_DEFAULT);
			}
			
			std::wstring name = browser->GetMiiName(selIndex+i);
			
			fileBtnText[i]->SetText(name);
			fileBtn[i]->SetPosition(x, y);
			
			tooltip[i]->SetText(name);
			if(40+x+tooltip[i]->GetWidth() > width)
				tooltip[i]->SetPosition(width-(40+x+tooltip[i]->GetWidth()), -30);
			else
				tooltip[i]->SetPosition(40, -30);
			tooltipBtn[i]->SetTooltip(tooltip[i]);
			tooltipBtn[i]->SetPosition(x, y);
		}
		else
		{
			fileBtn[i]->SetVisible(false);
			fileBtn[i]->SetState(STATE_DISABLED);
			tooltipBtn[i]->SetVisible(false);
			tooltipBtn[i]->SetState(STATE_DISABLED);
		}
		
		x += 90;
		if(x >= (u32) width-80)
		{
			x = 12;
			y += 90;
		}
	}
	
	for(int i = 0; i < PageSize; i++)
	{
		if(fileBtn[i]->GetState() == STATE_SELECTED && i != selItem)
		{
			fileBtn[i]->SetState(STATE_DEFAULT);
			tooltipBtn[i]->_SetState(STATE_DEFAULT);
		}
	}
	
	reloadNeeded = false;
	changing = false;
}

void IconMiiBrowser::OnBrowserListChange()
{
	if(numEntries != browser->GetEntrieCount())
	{
		numEntries = browser->GetEntrieCount();
		scrollbar->SetEntrieCount(numEntries);
	}

	forceReload = true;
	OnListChange(0, 0);
	
	scrollbar->SetSelectedItem(0);
	scrollbar->SetSelectedIndex(0);
}

void IconMiiBrowser::Update(GuiTrigger * t)
{
	bool ListChanged = false;
	
	if(t->Up())
	{
		if(pageIndex+selectedItem-RowSize >= 0)
		{
			selectedItem -= RowSize;
			if(selectedItem < 0)
			{
				//! move list up by 1
				pageIndex -= RowSize;
				selectedItem += RowSize;
			}
			ListChanged = true;
		}
		else
		{
			if((pageIndex =! 0) || (selectedItem =! 0))
				ListChanged = true;
			pageIndex = 0;
			selectedItem = 0;
		}
	}
	else if(t->Down())
	{
		int i = RowSize;
		while(pageIndex+selectedItem+RowSize >= numEntries && i > 0 && selectedItem > 0 && RowSize < numEntries)
		{
			--i;
			--selectedItem;
			ListChanged = true;
		}
		if(pageIndex+selectedItem+RowSize < numEntries)
		{
			selectedItem += RowSize;
			if(selectedItem >= PageSize)
			{
				//! move list down by 1
				pageIndex += RowSize;
				selectedItem -= RowSize;
			}
			
			ListChanged = true;
		}
	}
	else if(t->Left())
	{
		if(selectedItem + pageIndex - 1 >= 0)
		{
			selectedItem--;
			ListChanged = true;
		}
		
		if(selectedItem < 0)
		{
			selectedItem += RowSize;
			pageIndex -= RowSize;
		}
	}
	else if(t->Right())
	{
		if(selectedItem + pageIndex + 1 < numEntries)
		{
			selectedItem++;
			ListChanged = true;
		}
		
		if(selectedItem >= PageSize)
		{
			selectedItem -= RowSize;
			pageIndex += RowSize;
		}
	}
	
	if(ListChanged)
	{
		forceReload = true;
		OnListChange(selectedItem, pageIndex);
		
		scrollbar->SetSelectedItem(selectedItem);
		scrollbar->SetSelectedIndex(pageIndex);
	}
	
	GuiFileBrowser::Update(t);
}
